﻿using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using UIFramework;

#pragma warning disable 0414
public class UIManager : Singleton<UIManager>
{
    private string _respath = "Prefabs/UI/";
    /// <summary>
    /// 已经载入的UI
    /// </summary>
    private Dictionary<string, UIBase> _openedView = new Dictionary<string, UIBase>();
    /// <summary>
    /// 处于打开状态的UI名
    /// </summary>
    private List<string> _showingView = new List<string>();

    /// <summary>
    /// 静态UI父节点transform,主要处理场景内，位于交互UI下方的信息
    /// </summary>
    public Transform BottomCanvas { get; private set; }
    /// <summary>
    /// 主UI父节点transform，主要处理交互UI与交互绑定特效等
    /// </summary>
    public Transform MiddleCanvas { get; private set; }
    /// <summary>
    /// 效果UI父节点transform，主要处理浮于交互UI前的，与交互UI位置无关联的效果
    /// </summary>
    public Transform TopCanvas { get; private set; }
    /// <summary>
    /// UI摄像机
    /// </summary>
    public Camera UICamera { get; private set; }

    public override void Initialize()
    {
        Transform uiRoot = GameObject.Find("/UIRoot").transform;
        BottomCanvas = uiRoot.Find("BottomCanvas");
        MiddleCanvas = uiRoot.Find("MiddleCanvas");
        TopCanvas = uiRoot.Find("TopCanvas");
        UICamera = uiRoot.Find("UICamera").GetComponent<Camera>();
    }
    
    private void SetUIObjShow(Transform tran , bool show)
    {
        tran.gameObject.SetActive(show);
    }
    
    /// <summary>
    /// 设置生成界面的RECT信息
    /// </summary>
    /// <param name="res"></param>
    private void SetUIRectTrans(GameObject res)
    {
        if (res.GetComponent<Canvas>() == null)
        {
            res.AddComponent<Canvas>();
            res.AddComponent<GraphicRaycaster>();
        }
        //RectTransform rectrans = res.GetComponent<RectTransform>();
        //rectrans.anchoredPosition = Vector2.zero;
        //rectrans.localScale = Vector3.one;
        //rectrans.localRotation = Quaternion.identity;
        //rectrans.anchorMin = Vector2.zero;
        //rectrans.anchorMax = Vector2.one;
        //rectrans.pivot = 0.5f * Vector2.one;
        //rectrans.offsetMin = Vector2.zero;
        //rectrans.offsetMax = Vector2.zero;
        SetUIObjShow(res.transform, false);
    }
    /// <summary>
    /// 实例化UI
    /// </summary>
    /// <param name="UIName"></param>
    /// <returns></returns>
    private void LoadViewPerfab(string UIName, params object[] args)
    {
        UIBase uibase = GetGameUI(UIName);
        GameObject res = Resources.Load(_respath + UIName) as GameObject;
        if (res)
        {
            res = GameObject.Instantiate(res, GetCanvasTrans(uibase.GetUICanvas()));
            res.name = UIName;
            SetUIRectTrans(res);
            DoShowGameUI(res, uibase, true, args);
        }
        else
        {
            Debug.LogError($"[UIManager] LoadViewPerfab UI预制加载失败[{UIName}]");
        }
    }

    private Transform GetCanvasTrans(EUICanvas canvas)
    {
        switch (canvas)
        {
            case EUICanvas.Middle:
                return MiddleCanvas;
            case EUICanvas.Top:
                return TopCanvas;
            default:
                return BottomCanvas;
        }
    }

    /// <summary>
    /// 打开界面
    /// </summary>
    /// <param name="UIName"></param>
    public void ShowGameUI(string UIName, params object[] args)
    {
        if (string.IsNullOrEmpty(UIName))
        {
            return;
        }
        if (_openedView.TryGetValue(UIName, out var baseUI))
        {
            DoShowGameUI(baseUI.RootTrans.gameObject, baseUI, false, args);
        }
        else
        {
            LoadViewPerfab(UIName, args);
        }        
    }
    /// <summary>
    /// 执行显示界面
    /// </summary>
    /// <param name="view"></param>
    /// <param name="ui"></param>
    /// <param name="isNew"></param>
    private void DoShowGameUI(GameObject view, UIBase ui, bool isNew, params object[] args)
    {
        if (view == null || ui == null)
        {
            Debug.LogError($"[UIManager] view / ui 为空");
            return;
        }
        else
        {
            Transform vt = view.transform;
            vt.SetAsLastSibling();
            if (!_showingView.Contains(view.name))
            {
                SetUIObjShow(vt, true);
                _showingView.Add(view.name);
                if (isNew)
                {
                    ui.InitializeUI(vt);
                }
                ui.ShowUI(args);
                RefreshDepth();
            }
            else
            {
                Debug.LogWarning($"[UIManager] 重复打开UI:{view.name}");
            }
        }
    }

    private void RefreshDepth()
    {
        for (int i = 0; i < _showingView.Count; i++)
        {
            _openedView[_showingView[i]].SetDepth((i + 1) * 100);
        }
    }

    /// <summary>
    /// 根据名字创建UI类并返回
    /// </summary>
    /// <param name="vName"></param>
    /// <returns></returns>
    private UIBase GetGameUI(string vName)
    {
        UIBase bUI = UIUtility.GetUIClass(vName);
        if (bUI != null)
        {
            _openedView.Add(vName, bUI);
        }
        else
        {
            Debug.LogError($"[UIManager] 未找到名为[{vName}]的UI Class");
        }
        return bUI;
    }
    /// <summary>
    /// 关闭界面
    /// </summary>
    /// <param name="UIName"></param>
    public void CloseGameUI(string UIName,System.Action callback = null)
    {
        if (!_showingView.Contains(UIName)) return;
        if (_openedView.TryGetValue(UIName,out UIBase ui))
        {
            ui.CloseUI(() =>
            {
                SetUIObjShow(ui.RootTrans, false);
                _showingView.Remove(UIName);
                RefreshDepth();
                callback?.Invoke();
            });
        }
    }
    /// <summary>
    /// 销毁界面
    /// </summary>
    /// <param name="UIName"></param>
    public void DestoryGameUI(string UIName)
    {
        CloseGameUI(UIName, () =>
        {
            UIBase ui = _openedView[UIName];
            _openedView.Remove(UIName);
            ui.DestoryUI();
            GameObject.Destroy(ui.RootTrans.gameObject);
        });
    }
    /// <summary>
    /// 关闭某一画布下的全部UI
    /// </summary>
    /// <param name="canvas"></param>
    public void CloseAllGameUIInCanvas(EUICanvas canvas)
    {
        for (int i = _showingView.Count - 1; i >= 0 ; i--)
        {
            string name = _showingView[i];
            if (_openedView[name].GetUICanvas() == canvas)
            {
                CloseGameUI(name);
            }
        }
    }
    /// <summary>
    /// 关闭全部UI
    /// </summary>
    public void CloseAllGameUI()
    {
        for (int i = _showingView.Count - 1; i >= 0; i--)
        {
            CloseGameUI(_showingView[i]);
        }
    }
    /// <summary>
    /// 销毁某一画布下的全部UI
    /// </summary>
    /// <param name="canvas"></param>
    public void DestroyAllGameUIInCanvas(EUICanvas canvas)
    {
        List<string> nameList = new List<string>();
        nameList.AddRange(_openedView.Keys);
        foreach (string name in nameList)
        {
            if (_openedView[name].GetUICanvas() == canvas)
            {
                DestoryGameUI(name);
            }
        }
    }
    /// <summary>
    /// 销毁全部UI
    /// </summary>
    public void DestroyAllGameUI()
    {
        List<string> nameList = new List<string>();
        nameList.AddRange(_openedView.Keys);
        foreach (string name in nameList)
        {
            DestoryGameUI(name);
        }
    }
    /// <summary>
    /// 某一UI是否已打开
    /// </summary>
    /// <param name="UIName"></param>
    /// <returns></returns>
    public bool IsTheUIShowing(string UIName)
    {
        return _showingView.Contains(UIName);
    }

    /// <summary>
    /// UI是否打开过
    /// </summary>
    /// <param name="UIName"></param>
    /// <returns></returns>
    public bool IsUIOpened(string UIName)
    {
        return _openedView.ContainsKey(UIName);
    }

    public UIBase GetUIByName(string name)
    {
        if (_openedView.TryGetValue(name,out var ui))
        {
            return ui;
        }
        return null;
    }
}

/// <summary>
/// 对应三层画布的枚举
/// </summary>
public enum EUICanvas { Bottom, Middle, Top }

